{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 异常\n",
    "- 广义上的错误分为错误和异常\n",
    "- 错误指的是可以人为避免\n",
    "- 异常是指在语法逻辑正确的前提下，出现的问题\n",
    "- 在python里，异常是一个类，可以处理和使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 异常的分类\n",
    "\n",
    "    AssertError 断言语句（assert）失败\n",
    "    AttributeError 尝试访问未知的对象属性\n",
    "    EOFError 用户输入文件末尾标志EOF（Ctrl+d）\n",
    "    FloatingPointError 浮点计算错误\n",
    "    GeneratorExit generator.close()方法被调用的时候\n",
    "    ImportError 导入模块失败的时候\n",
    "    IndexError 索引超出序列的范围\n",
    "    KeyError 字典中查找一个不存在的关键字\n",
    "    KeyboardInterrupt 用户输入中断键（Ctrl+c）\n",
    "    MemoryError 内存溢出（可通过删除对象释放内存）\n",
    "    NameError 尝试访问一个不存在的变量\n",
    "    NotImplementedError 尚未实现的方法\n",
    "    OSError 操作系统产生的异常（例如打开一个不存在的文件）\n",
    "    OverflowError 数值运算超出最大限制\n",
    "    ReferenceError 弱引用（weak reference）试图访问一个已经被垃圾回收机制回收了的对象\n",
    "    RuntimeError 一般的运行时错误\n",
    "    StopIteration 迭代器没有更多的值\n",
    "    SyntaxError Python的语法错误\n",
    "    IndentationError 缩进错误\n",
    "    TabError Tab和空格混合使用\n",
    "    SystemError Python编译器系统错误\n",
    "    SystemExit Python编译器进程被关闭\n",
    "    TypeError 不同类型间的无效操作\n",
    "    UnboundLocalError 访问一个未初始化的本地变量（NameError的子类）\n",
    "    UnicodeError Unicode相关的错误（ValueError的子类）\n",
    "    UnicodeEncodeError Unicode编码时的错误（UnicodeError的子类）\n",
    "    UnicodeDecodeError Unicode解码时的错误（UnicodeError的子类）\n",
    "    UnicodeTranslateError Unicode转换时的错误（UnicodeError的子类）\n",
    "    ValueError 传入无效的参数\n",
    "    ZeroDivisionError 除数为零\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plz input your num:0\n"
     ]
    },
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-10-e4973da5bbf2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;31m# 常常犯的除零错误\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mnum\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Plz input your num:\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m100\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mnum\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
     ],
     "output_type": "error"
    }
   ],
   "source": [
    "l = [1,2,3,4,5]\n",
    "# 常常犯的除零错误\n",
    "num = int(input(\"Plz input your num:\"))\n",
    "print(100/num)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 异常处理\n",
    "- 不能保证程序永远正确运行\n",
    "- 但是，必须保证程序在最坏的情况下得到的问题被妥善处理\n",
    "- python的异常处理模块全部语法为：\n",
    "\n",
    "        try:\n",
    "            尝试实现某个操作，\n",
    "            如果没出现异常，任务就可以完成\n",
    "            如果出现异常，将异常从当前代码块扔出去尝试解决异常\n",
    "        \n",
    "        except 异常类型1:\n",
    "            解决方案1：用于尝试在此处处理异常解决问题\n",
    "\n",
    "        except 异常类型2：\n",
    "            解决方案2：用于尝试在此处处理异常解决问题\n",
    "\n",
    "        except (异常类型1,异常类型2...)\n",
    "            解决方案：针对多个异常使用相同的处理方式\n",
    "\n",
    "        excpet:\n",
    "            解决方案：所有异常的解决方案\n",
    "\n",
    "        else:\n",
    "            如果没有出现任何异常，将会执行此处代码\n",
    "\n",
    "        finally:\n",
    "            管你有没有异常都要执行的代码\n",
    "\n",
    "- 流程\n",
    "    1. 执行try下面的语句\n",
    "    2. 如果出现异常，则在except语句里查找对应异常病进行处理\n",
    "    3. 如果没有出现异常，则执行else语句内容\n",
    "    4. 最后，不管是否出现异常，都要执行finally语句\n",
    "- 除except(最少一个)以外，else和finally可选\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plz input your number:0\n",
      "你特娘的输入的啥玩意儿\n"
     ]
    }
   ],
   "source": [
    "# 简单异常案例\n",
    "try:\n",
    "    num = int(input(\"Plz input your number:\"))\n",
    "    rst = 100/num\n",
    "    print(\"计算结果是： {0}\".format(rst))\n",
    "except:\n",
    "    print(\"你特娘的输入的啥玩意儿\")\n",
    "    # exit是退出程序的意思\n",
    "    exit()\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plz input your number:0\n",
      "你特娘的输入的啥玩意儿\n",
      "division by zero\n"
     ]
    }
   ],
   "source": [
    "# 简单异常案例\n",
    "# 给出提示信息\n",
    "try:\n",
    "    num = int(input(\"Plz input your number:\"))\n",
    "    rst = 100/num\n",
    "    print(\"计算结果是： {0}\".format(rst))\n",
    "# 捕获异常后，把异常实例化，出息信息会在实例里\n",
    "# 注意以下写法\n",
    "# 以下语句是捕获ZeroDivisionError异常并实例化实例e\n",
    "except ZeroDivisionError as e:\n",
    "    print(\"你特娘的输入的啥玩意儿\")\n",
    "    print(e)\n",
    "    # exit是退出程序的意思\n",
    "    exit()\n",
    "    \n",
    "# 作业： 为什么我们可以直接打印出实例e，此时实例e应该实现了哪个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plz input your number:rerer\n",
      "我也不知道就出错了\n",
      "invalid literal for int() with base 10: 'rerer'\n",
      "hahahhaahh\n"
     ]
    }
   ],
   "source": [
    "# 简单异常案例\n",
    "# 给出提示信息\n",
    "try:\n",
    "    num = int(input(\"Plz input your number:\"))\n",
    "    rst = 100/num\n",
    "    print(\"计算结果是： {0}\".format(rst))\n",
    "\n",
    "# 如果是多种error的情况\n",
    "# 需要把越具体的错误，越往前放\n",
    "# 在异常类继承关系中，越是子类的异常，越要往前放，\n",
    "# 越是父亲类的异常，越要往后放\n",
    "\n",
    "# 在处理异常的时候，一旦拦截到某一个异常，则不在继续往下查看，直接进行下一个\n",
    "# 代码，即有finally则执行finally语句块，否则就执行下一个大的语句\n",
    "except ZeroDivisionError as e:\n",
    "    print(\"你特娘的输入的啥玩意儿\")\n",
    "    print(e)\n",
    "    # exit是退出程序的意思\n",
    "    exit()\n",
    "except NameError as e:\n",
    "    print(\"名字起错了\")\n",
    "    print(e)\n",
    "\n",
    "except AttributeError as e:\n",
    "    print(\"好像属性有问题\")\n",
    "    print(e)\n",
    "    exit()\n",
    "    \n",
    "# 所有异常都是继承自Exception\n",
    "# 如果写上下面这句话，任何异常都会拦截住\n",
    "# 而且，下面这句话一定是最后一个exception\n",
    "except Exception as e:\n",
    "    print(\"我也不知道就出错了\")\n",
    "    print(e)\n",
    "    \n",
    "except ValueError as e:\n",
    "    print(\"NO>>>>>>>>>>>>>>>>>>\")\n",
    "    \n",
    "    \n",
    "print(\"hahahhaahh\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 用户手动引发异常\n",
    "- 当某些情况，用户希望自己引发一个异常的时候，可以使用\n",
    "- raise 关键字来引发异常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我爱王晓静\n",
      "3.1415926\n",
      "ValueError\n",
      "我肯定会被执行的\n"
     ]
    }
   ],
   "source": [
    "# raise案例-1\n",
    "try:\n",
    "    print(\"我爱王晓静\")\n",
    "    print(3.1415926)\n",
    "    # 手动引发一个异常\n",
    "    #　注意语法：　raise　ＥｒｒｏｒＣｌａｓｓＮａｍｅ\n",
    "    raise ValueError\n",
    "    print(\"还没完呀\")\n",
    "except NameError as e:\n",
    "    print(\"NameError\")\n",
    "except ValueError as e:\n",
    "    print(\"ValueError\")\n",
    "except Exception as e:\n",
    "    print(\"有异常\")\n",
    "finally:\n",
    "    print(\"我肯定会被执行的\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我爱王晓静\n",
      "3.1415926\n",
      "ValueError\n",
      "我肯定会被执行的\n"
     ]
    }
   ],
   "source": [
    "# raise案例-2\n",
    "# 自己定义异常\n",
    "# 需要注意：　自定义异常必须是系统异常的子类\n",
    "class DanaValueError(ValueError):\n",
    "    pass\n",
    "\n",
    "try:\n",
    "    print(\"我爱王晓静\")\n",
    "    print(3.1415926)\n",
    "    # 手动引发一个异常\n",
    "    #　注意语法：　raise　ＥｒｒｏｒＣｌａｓｓＮａｍｅ\n",
    "    raise DanaValueError\n",
    "    print(\"还没完呀\")\n",
    "except NameError as e:\n",
    "    print(\"NameError\")\n",
    "except ValueError as e:\n",
    "    print(\"ValueError\")\n",
    "except Exception as e:\n",
    "    print(\"有异常\")\n",
    "finally:\n",
    "    print(\"我肯定会被执行的\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plz input your number:ghhj\n",
      "Exception\n",
      "反正我会被执行\n"
     ]
    }
   ],
   "source": [
    "# else语句案例\n",
    "\n",
    "try:\n",
    "    num = int(input(\"Plz input your number:\"))\n",
    "    rst = 100/num\n",
    "    print(\"计算结果是： {0}\".format(rst))\n",
    "except Exception as e:\n",
    "    print(\"Exception\")\n",
    "    \n",
    "else:\n",
    "    print(\"No Exception\")\n",
    "finally:\n",
    "    print(\"反正我会被执行\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 关于自定义异常\n",
    "- 只要是raise异常，则推荐自定义异常\n",
    "- 在自定义异常的时候，一般包含以下内容：\n",
    "    - 自定义发生异常的异常代码\n",
    "    - 自定义发生异常后的问题提示\n",
    "    - 自定义发生异常的行数\n",
    "- 最终的目的是，一旦发生异常，方便程序员快速定位错误现场"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'pritn' is not defined",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-10-2f9e2f4cb593>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpritn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"hahah\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'pritn' is not defined"
     ],
     "output_type": "error"
    }
   ],
   "source": [
    "pritn(\"hahah\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'pritn' is not defined",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-3-ba6014a29f03>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpritn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"hahahah\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'pritn' is not defined"
     ],
     "output_type": "error"
    }
   ],
   "source": [
    " pritn(\"hahahah\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hj"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
